package org.compiere.process;

import java.math.BigDecimal;
import java.math.MathContext;
import java.math.RoundingMode;
import java.sql.Array;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Timestamp;
import java.util.Iterator;
import java.util.Set;
import java.util.logging.Level;

import org.adempiere.exceptions.DBException;
import org.compiere.apps.ADialog;
import org.compiere.model.MFactAcct;
import org.compiere.model.MJournal;
import org.compiere.model.MJournalBatch;
import org.compiere.model.MJournalLine;
import org.compiere.model.MPeriod;
import org.compiere.model.MSequence;
import org.compiere.model.X_A_Depreciation_Build;
import org.compiere.model.X_C_Period;
import org.compiere.model.X_GL_Category;
import org.compiere.process.ProcessInfoParameter;
import org.compiere.process.SvrProcess;
import org.compiere.util.CLogger;
import org.compiere.util.DB;
import org.compiere.util.Env;
import org.zkoss.zul.Calendar;

public class TaxCloseMonth extends SvrProcess{
	
	private int c_period_id;
	private int p_AD_Client_ID;
	private int p_AD_Org_ID;
	private int p_AD_User_ID;

	
	private Timestamp time = null;
	
	private String description = null;
	private String postingType = null;
	private String docStatus = null;
	private String documentNo = null;
	private String docAction = null;
	
	private int c_conversiontype_id = 0;
	private int gl_category_id = 0;
	private int c_currency_id = 0;
	private int c_doctype_id = 0;
	
	private int VAT_offsetting = 0;
	private int VAT_deduction = 0;
	
	private CLogger Log = CLogger.getCLogger(TaxCloseMonth.class);
	
	@Override
	protected void prepare(){
		ProcessInfoParameter[] para = getParameter();
		for (int i = 0; i < para.length; i++)	{
			String name = para[i].getParameterName();
			if (para[i].getParameter() == null); 
			else if (para[i].getParameterName().compareTo("C_Period_ID") == 0)
			{
				c_period_id = Integer.parseInt(para[i].getParameter().toString());
			}
			else if (para[i].getParameterName().compareTo("VAT_offsetting") == 0)
			{
				VAT_offsetting = Integer.parseInt(para[i].getParameter().toString());
			}
			else if (para[i].getParameterName().compareTo("VAT_deduction") == 0)
			{
				VAT_deduction = Integer.parseInt(para[i].getParameter().toString());
			}
			else
			{
				log.log(Level.SEVERE, "Unknown Parameter: " + name);
			}
		}
		
		p_AD_Client_ID = Env.getAD_Client_ID(getCtx());
		p_AD_Org_ID = Env.getAD_Org_ID(getCtx());
	 	p_AD_User_ID = Env.getAD_User_ID(getCtx());
	}
	
	/* (non-Javadoc)
	 * @see org.compiere.process.SvrProcess#doIt()
	 */
	@Override
	protected String doIt() throws Exception 
	{
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		
		//142000
		int accountID1 = 0;
		//313000
		int accountID2 = 0;
		
		StringBuffer sql = new StringBuffer();
		String clientCheck = " AND AD_Client_ID=" + getAD_Client_ID();
		
		sql.setLength(0);		
		sql.append("SELECT account_id from adempiere.c_validcombination where c_validcombination_id = " + VAT_offsetting);
		accountID1 = DB.getSQLValue(get_TrxName(), sql.toString());
		if(accountID1 < 0) return "Error account_id 1";
		
		sql.setLength(0);		
		sql.append("SELECT account_id from adempiere.c_validcombination where c_validcombination_id = " + VAT_deduction);
		accountID2 = DB.getSQLValue(get_TrxName(), sql.toString());
		if(accountID2 < 0) return "Error account_id 2";

		MPeriod period = new MPeriod(getCtx(), c_period_id, null);
		
		String sqlEndDate = "select enddate, startdate from adempiere.c_period where c_period_id = " + c_period_id;
		pstmt = DB.prepareStatement(sqlEndDate, get_TrxName());
		rs = pstmt.executeQuery();
		
		Timestamp startDate = null;
		Timestamp endDate = null;
		
		try
		{
			if(rs.next())
			{
				startDate = rs.getTimestamp("startdate");
				endDate = rs.getTimestamp("enddate");
			}
		}
		catch(Exception e){}
		
		//Set C_DocType_ID
		sql.setLength(0);
        sql.append("SELECT C_DocType_ID FROM C_DocType"
		+ " WHERE Name='Closing of VAT' AND DocBaseType='GLJ' AND isActive ='Y'"+clientCheck);        
        c_doctype_id = DB.getSQLValue(get_TrxName(), sql.toString());
		if (c_doctype_id<0) return "Error DocTypeID";
		
		sql.setLength(0);		
		sql.append("SELECT GL_JournalBatch_ID FROM ADEMPIERE.GL_JournalBatch WHERE DOCSTATUS = 'CO' AND C_PERIOD_ID = " + String.valueOf(c_period_id)
				+ " AND C_DOCTYPE_ID = " + c_doctype_id);
		int batchID = DB.getSQLValue(get_TrxName(), sql.toString());
		
		ADialog dialog = new ADialog();
		
		if(batchID != -1)
		{
			if(dialog.ask(25, null, "Процесс \"Закрытие месяца. НДС\" уже был успешно завершен. Вы хотите запустить данный процесс повторно?"))
			{
				ReWriteBatch(batchID, period, accountID1, accountID2);
			}
			else
			{
				return "Операция отменена";
			}
		}
		
		//Set C_Currency_ID
		sql.setLength(0);
        sql.append("SELECT C_Currency_ID FROM C_AcctSchema "
		+ " WHERE isActive='Y'"+clientCheck);
        c_currency_id = DB.getSQLValue(get_TrxName(), sql.toString());
		if (c_currency_id<0) return "Error CurrencyID";
		
		//Set GL_Catecory_ID
		sql.setLength(0);
        sql.append("SELECT GL_Category_ID FROM GL_Category "
		+ " WHERE isActive='Y' AND CategoryType = '"+X_GL_Category.CATEGORYTYPE_Manual+"'"
        +" AND isDefault = 'Y'"+clientCheck);
        gl_category_id = DB.getSQLValue(get_TrxName(), sql.toString());
		if (gl_category_id<0) return "Error GL CategoryID";
		
		//Set Conversion Type
		sql.setLength(0);
		sql.append("SELECT C_ConversionType_ID FROM C_ConversionType "
		+ " WHERE isActive='Y' AND isDefault = 'Y' AND NAME = 'Daily'");
		//c_conversiontype_id = DB.getSQLValue(get_TrxName(), sql.toString());
		c_conversiontype_id = DB.getSQLValue(get_TrxName(), sql.toString());
		if (c_conversiontype_id<0) return "Error Conversion Type ID";
		
		//Set Conversion Type
		sql.setLength(0);
		sql.append("SELECT C_ConversionType_ID FROM C_ConversionType "
		+ " WHERE isActive='Y' AND isDefault = 'Y'");
		//c_conversiontype_id = DB.getSQLValue(get_TrxName(), sql.toString());
		c_conversiontype_id = 114;		
		if (c_conversiontype_id<0) return "Error Conversion Type ID";
		
		X_C_Period Period = new X_C_Period(getCtx(), c_period_id, null);
		
		//description = "Закрытие месяца (НДС) за " + new java.text.SimpleDateFormat("MMMMMMM").format(Period.getEndDate().getTime());
		
		postingType = MJournalBatch.POSTINGTYPE_Actual;
		docStatus = MJournalBatch.STATUS_InProgress;
		docAction = MJournalBatch.ACTION_Prepare;
		
		MJournalBatch batch = new MJournalBatch(getCtx(), 0, null);		
		
		String dn = MSequence.getDocumentNo (p_AD_Client_ID, "gl_journalbatch", get_TrxName(), batch);
		if (dn == null)
			throw new DBException ("No DocumentNo");
		
		description = documentNo = dn;
		
		/*sql.setLength(0);
        sql.append("SELECT c_acctschema_id FROM GL_Category "
		+ " WHERE isActive='Y' "+clientCheck);
        int C_AcctSchema_ID = DB.getSQLValue(get_TrxName(), sql.toString());
		if (C_AcctSchema_ID < 0) return "Error C_AcctSchema_ID";
		*/
		int C_AcctSchema_ID = 1000000;
		
		String documentNo2 = documentNo + "J";
				
		batch.setClientOrg(p_AD_Client_ID, p_AD_Org_ID);
		batch.setDocumentNo(documentNo);
		batch.setDescription(description);
		batch.setPostingType(X_A_Depreciation_Build.POSTINGTYPE_Actual);
		batch.setGL_Category_ID(gl_category_id);
		batch.setDateDoc(Period.getEndDate());
		batch.setDateAcct(Period.getEndDate());
		batch.setC_Period_ID(c_period_id);
		batch.setC_Currency_ID(c_currency_id);
		batch.setControlAmt(BigDecimal.valueOf(0));
		batch.setC_DocType_ID(c_doctype_id);
		batch.setDocStatus(docStatus);
		batch.setDocAction(docAction);
		batch.setProcessing(true);
		batch.setProcessed(true);
		
		if (!batch.save()) {
			Log.log(Level.SEVERE, "Batch Journal not saved - " + batch.getDocumentNo());
		}
		
		MJournal journal = new MJournal(batch);
		
		journal.setClientOrg(getAD_Client_ID(), p_AD_Org_ID);
		journal.setIsActive(true);
		journal.setC_AcctSchema_ID(C_AcctSchema_ID);
		journal.setC_DocType_ID(batch.getC_DocType_ID());
		journal.setDocumentNo(documentNo2);
		journal.setDocStatus(docStatus);
		journal.setDocAction("--");
		journal.setIsApproved(true);
		journal.setIsPrinted(false);
		journal.setDescription(description);
		journal.setPostingType(batch.getPostingType());
		journal.setGL_Category_ID(batch.getGL_Category_ID());
		journal.setDateDoc(batch.getDateDoc());
		journal.setDateAcct(batch.getDateAcct());
		journal.setC_Period_ID(batch.getC_Period_ID());
		journal.setCurrencyRate(new BigDecimal(1));
		journal.setControlAmt(new BigDecimal(0));
		journal.setC_ConversionType_ID(c_conversiontype_id);
		journal.setProcessing(true);
		journal.setProcessed(true);
		journal.setPosted(true);
		if (!journal.save()) {
			Log.log(Level.SEVERE, "Journal not saved - "+batch.getDocumentNo()+ " " +journal.getDocumentNo());
		} 
		
		//Set Conversion Type
		sql.setLength(0);
		sql.append("SELECT ad_table_id FROM ad_table "
		+ " WHERE tablename='C_Invoice'");
		int ad_table = DB.getSQLValue(get_TrxName(), sql.toString());
		if (ad_table<0) return "Error ad_table_id";
		
		sql.setLength(0);
		sql.append("SELECT ad_table_id FROM ad_table "
		+ " WHERE tablename='GL_Journal'");
		int ad_table2 = DB.getSQLValue(get_TrxName(), sql.toString());
		if (ad_table2<0) return "Error ad_table_id 2";
		
		String sqlBeging = "select sum(f.amtsourcecr), sum(f.amtsourcedr), e.value from adempiere.fact_acct f inner join adempiere.c_elementvalue e on f.account_id = e.c_elementvalue_id"
				+ " where f.dateacct between '2011-01-01' and '" + startDate + "' and f.account_id in (" + accountID1 + ", " + accountID2 + ")"
				+ " group by e.value"
				+ " order by e.value";
		
		String sqlEnd = "select sum(f.amtsourcecr), sum(f.amtsourcedr), e.value from adempiere.fact_acct f inner join adempiere.c_elementvalue e on f.account_id = e.c_elementvalue_id"
				+ " where f.dateacct between '" + startDate + "' and '" + endDate + "' and f.account_id in (" + accountID1 + ", " + accountID2 + ")"
				+ " group by e.value"
				+ " order by e.value";
		
//		String sqlSum = "select sum(f.amtsourcecr), sum(f.amtsourcedr), e.value from adempiere.fact_acct f inner join adempiere.c_elementvalue e on " +
//				"f.account_id = e.c_elementvalue_id  where f.dateacct between '2011-01-01' and '" + endDate + "' and f.ad_table_id = " + ad_table + " and f.account_id in (1000030,1000055)" + 
//				"group by e.value";
		
		double sumBalanceBegin = 0.0;
		double sumBalanceEnd = 0.0;
		
		double sumCrEnd = 0.0;
		double sumDrEnd = 0.0;
		
		double sumCredit = 0.0;
		double sumDebit = 0.0;
		try
		{
			pstmt = DB.prepareStatement(sqlBeging, get_TrxName());
			rs = pstmt.executeQuery();			
			
			while(rs.next())
			{			
				if(rs.getString("value").startsWith("3"))
				{
					sumBalanceBegin = rs.getBigDecimal(1).doubleValue() - rs.getBigDecimal(2).doubleValue();
				}
				if(rs.getString("value").startsWith("1"))
				{
					sumBalanceEnd = rs.getBigDecimal(2).doubleValue() - rs.getBigDecimal(1).doubleValue();
				}
					//sumDebit = sumDebit > rs.getBigDecimal(2).doubleValue() ? sumDebit : rs.getBigDecimal(2).doubleValue();
					//sumCredit = sumDebit > rs.getBigDecimal(2).doubleValue() ? sumCredit : rs.getBigDecimal(1).doubleValue();			
					//sumDebit += rs.getBigDecimal(2).doubleValue();
					//sumCredit += rs.getBigDecimal(1).doubleValue();	
					
			}
		}		
		catch (Exception e) {}
		
		try
		{
			pstmt = DB.prepareStatement(sqlEnd, get_TrxName());
			rs = pstmt.executeQuery();			
			
			while(rs.next())
			{			
				if(rs.getString("value").startsWith("3"))
				{
					sumBalanceBegin = rs.getBigDecimal(1).doubleValue() - rs.getBigDecimal(2).doubleValue() + sumBalanceBegin;
				}
				if(rs.getString("value").startsWith("1"))
				{
					sumBalanceEnd = rs.getBigDecimal(2).doubleValue() - rs.getBigDecimal(1).doubleValue() + sumBalanceEnd;
				}
			}
		}		
		catch (Exception e) {}
		
		//sumDebit = 
		
		sumDebit = sumBalanceBegin > sumBalanceEnd ? sumBalanceEnd : sumBalanceBegin;
		sumCredit = 0.0;

		int validation1 = -1;
		int validation2 = -1;
	
		//Set GL_Catecory_ID
		sql.setLength(0);
		sql.append("SELECT c_validcombination_id FROM c_validcombination "
		+ " WHERE isActive='Y' AND account_id = " + accountID1 + " and ad_org_id = " + p_AD_Org_ID + clientCheck);
		validation1 = DB.getSQLValue(get_TrxName(), sql.toString());
		if (validation1<0) return "Error C_ValidCombination_ID";
		
		//Set GL_Catecory_ID
		sql.setLength(0);
		sql.append("SELECT c_validcombination_id FROM c_validcombination "
		+ " WHERE isActive='Y' AND account_id = " + accountID2 + " and ad_org_id = " + p_AD_Org_ID + clientCheck);
		validation2 = DB.getSQLValue(get_TrxName(), sql.toString());
		if (validation2<0) return "Error C_ValidCombination_ID2";
		
		MJournalLine line1 = new MJournalLine(journal);
		MJournalLine line2 = new MJournalLine(journal);
			
		line1.setAD_Org_ID(p_AD_Org_ID);
		line1.setLine(10);
		line1.setAmtSourceCr(BigDecimal.valueOf(sumCredit));
		line1.setAmtSourceDr(BigDecimal.valueOf(sumDebit));
		line1.setCurrency(journal.getC_Currency_ID(), journal.getC_ConversionType_ID(), new BigDecimal(1));
		line1.setDateAcct(journal.getDateAcct());
		line1.setAmtAcctCr(BigDecimal.valueOf(sumCredit));
		line1.setAmtAcctDr(BigDecimal.valueOf(sumDebit));
		line1.setC_ValidCombination_ID(validation2);
		line1.setProcessed(true);
		line1.setA_CreateAsset(false);
		line1.setA_Processed(false);
		if (!line1.save()) {
			Log.log(Level.SEVERE, "Line number one not saved - " + batch.getDocumentNo()+ " " +line1.getDescription());
		}
				
		MJournalLine.copyValues(line1, line2);
		
		line2.setAmtSourceCr(BigDecimal.valueOf(sumDebit));
		line2.setAmtSourceDr(BigDecimal.valueOf(sumCredit));				
		line2.setAmtAcctCr(BigDecimal.valueOf(sumDebit));
		line2.setAmtAcctDr(BigDecimal.valueOf(sumCredit));
		line2.setC_ValidCombination_ID(validation1);
		if (!line2.save()) {
			Log.log(Level.SEVERE, "Line number one not saved - " + batch.getDocumentNo()+ " " +line2.getDescription());
		}
				
		MFactAcct fact = new MFactAcct(getCtx(), 0, get_TrxName());					

		fact.setAD_Org_ID(p_AD_Org_ID);
		fact.setC_AcctSchema_ID(journal.getC_AcctSchema_ID());
		fact.setC_Period_ID(journal.getC_Period_ID());		
		fact.setAmtSourceCr(BigDecimal.valueOf(sumCredit));
		fact.setAmtSourceDr(BigDecimal.valueOf(sumDebit));
		fact.setAmtAcctCr(BigDecimal.valueOf(sumCredit));
		fact.setAmtAcctDr(BigDecimal.valueOf(sumDebit));
		fact.setDateAcct(journal.getDateAcct());
		fact.setDateTrx(journal.getDateDoc());
		fact.setRecord_ID(journal.get_ID());
		fact.setC_BPartner_ID(0);
		fact.setAD_Table_ID(ad_table2);
		fact.setAccount_ID(accountID2);
		fact.setLine_ID(line1.get_ID());
		fact.setPostingType(journal.getPostingType());
		fact.setC_Currency_ID(journal.getC_Currency_ID());	
		if (!fact.save()) {
			Log.log(Level.SEVERE, "Line number one not saved - " + batch.getDocumentNo()+ " " +fact.getDescription());
		}
					
		MFactAcct fact2 = new MFactAcct(getCtx(), 0, get_TrxName());	
		MFactAcct.copyValues(fact, fact2);
		fact2.setAmtSourceDr(BigDecimal.valueOf(sumCredit));
		fact2.setAmtSourceCr(BigDecimal.valueOf(sumDebit));
		fact2.setAmtAcctDr(BigDecimal.valueOf(sumCredit));
		fact2.setAmtAcctCr(BigDecimal.valueOf(sumDebit));
		fact2.setRecord_ID(journal.get_ID());
		fact2.setDateAcct(journal.getDateAcct());
		fact2.setDateTrx(journal.getDateDoc());

		fact2.setAD_Table_ID(ad_table2);
		fact2.setAccount_ID(accountID1);
		fact2.setC_BPartner_ID(0);
		if (!fact2.save()) {
			Log.log(Level.SEVERE, "Line number one not saved - " + batch.getDocumentNo()+ " " +fact2.getDescription());
		}
				
		MathContext context = new MathContext(7);
		
//		journal.setTotalCr(BigDecimal.valueOf(sumDebit).round(context));
		journal.setTotalCr(BigDecimal.valueOf(sumDebit).setScale(2, RoundingMode.HALF_UP));
//		journal.setTotalDr(BigDecimal.valueOf(sumDebit).round(context));
		journal.setTotalDr(BigDecimal.valueOf(sumDebit).setScale(2,RoundingMode.HALF_UP));

//		batch.setTotalCr(BigDecimal.valueOf(sumDebit).round(context));
		batch.setTotalCr(BigDecimal.valueOf(sumDebit).setScale(2, RoundingMode.HALF_UP));

//		batch.setTotalDr(BigDecimal.valueOf(sumDebit).round(context));
		batch.setTotalDr(BigDecimal.valueOf(sumDebit).setScale(2, RoundingMode.HALF_UP));
		
		journal.setDocStatus(MJournalBatch.STATUS_Completed);
		batch.setDocStatus(MJournalBatch.STATUS_Completed);
		
		if (!journal.save()) {
			Log.log(Level.SEVERE, "Line number one not saved - " + batch.getDocumentNo()+ " " +journal.getDocumentNo());
		}
		if (!batch.save()) {
			Log.log(Level.SEVERE, "Line number one not saved - " + batch.getDocumentNo());
		}
		return "Процесс \"Закрытие месяца. НДС\" завершен успешно";
	}
	
	private boolean ReWriteBatch(int batchID, MPeriod Period, int accountID1, int accountID2)
	{
		MJournalBatch batch = new MJournalBatch(getCtx(), batchID, null);
		
		MJournal[] journals = batch.getJournals(true);
		
		MJournalLine[] lines = journals[0].getLines(true);
		
		batch.setDocStatus(MJournalBatch.STATUS_InProgress);
		
		batch.setDocAction(MJournalBatch.ACTION_Complete);
		
		batch.save();
		
		String dn = MSequence.getDocumentNo (p_AD_Client_ID, "gl_journalbatch", get_TrxName(), batch);
		if (dn == null)
			throw new DBException ("No DocumentNo");
		
		documentNo = dn;
		
		MJournalBatch batch2 = new MJournalBatch(getCtx(), null, get_TrxName());
		batch2.setClientOrg(p_AD_Client_ID, p_AD_Org_ID);
		batch2.setDocumentNo(documentNo);
		batch2.setDescription(batch.getDocumentNo());
		batch2.setPostingType(X_A_Depreciation_Build.POSTINGTYPE_Actual);
		batch2.setGL_Category_ID(batch.getGL_Category_ID());
		batch2.setDateDoc(batch.getDateDoc());
		batch2.setDateAcct(batch.getDateAcct());
		batch2.setC_Period_ID(batch.getC_Period_ID());
		batch2.setC_Currency_ID(batch.getC_Currency_ID());
		batch2.setControlAmt(BigDecimal.valueOf(0));
		batch2.setC_DocType_ID(batch.getC_DocType_ID());
		batch2.setProcessing(true);
		batch2.setProcessed(true);
		
		batch2.setDocStatus(MJournalBatch.STATUS_InProgress);
		batch2.setDocAction(MJournalBatch.ACTION_Prepare);
		if (!batch2.save()) {
			Log.log(Level.SEVERE, "Journal not saved - "+batch.getDocumentNo()+ " " +batch2.getDocumentNo());
		} 
		
		batch.setDescription(documentNo);
		
		MJournal journal = new MJournal(batch2);
		
		journal.setClientOrg(getAD_Client_ID(), p_AD_Org_ID);
		journal.setIsActive(true);
		journal.setC_AcctSchema_ID(1000000);
		journal.setC_DocType_ID(batch.getC_DocType_ID());
		journal.setDocumentNo(batch.getDocumentNo() + "2");
		journal.setDocStatus(batch.getDocStatus());
		journal.setDocAction("--");
		journal.setIsApproved(true);
		journal.setIsPrinted(false);
		journal.setDescription(batch.getDescription());
		journal.setPostingType(batch.getPostingType());
		journal.setGL_Category_ID(batch.getGL_Category_ID());
		journal.setDateDoc(batch.getDateDoc());
		journal.setDateAcct(batch.getDateAcct());
		journal.setC_Period_ID(batch.getC_Period_ID());
		journal.setCurrencyRate(new BigDecimal(1));
		journal.setControlAmt(new BigDecimal(0));
		journal.setC_ConversionType_ID(114);
		journal.setProcessing(true);
		journal.setProcessed(true);
		journal.setPosted(true);
		if (!journal.save()) {
			Log.log(Level.SEVERE, "Journal not saved - "+batch.getDocumentNo()+ " " +journal.getDocumentNo());
		} 
		
		for (MJournalLine line : lines) 
		{			
			MJournalLine newLine = new MJournalLine(journal);
								
			newLine.setAD_Org_ID(p_AD_Org_ID);
			newLine.setIsActive(true);
			newLine.setLine(100);
			newLine.setCurrency(341, 114, new BigDecimal(1));
			newLine.setDateAcct(journals[0].getDateAcct());
			newLine.setC_ValidCombination_ID(line.getC_ValidCombination_ID());
			newLine.setProcessed(true);
			newLine.setA_CreateAsset(false);
			newLine.setA_Processed(false);
			
			newLine.setAmtAcctCr(line.getAmtAcctCr().negate());
			newLine.setAmtAcctDr(line.getAmtAcctDr().negate());			
			newLine.setAmtSourceCr(line.getAmtSourceCr().negate());
			newLine.setAmtSourceDr(line.getAmtSourceDr().negate());
			
			newLine.save();
			
			MFactAcct acct = new MFactAcct(getCtx(), null, get_TrxName());
			acct.setAmtAcctCr(line.getAmtAcctCr().negate());
			acct.setAmtAcctDr(line.getAmtAcctDr().negate());					
			acct.setAmtSourceCr(line.getAmtSourceCr().negate());
			acct.setAmtSourceDr(line.getAmtSourceDr().negate());
			acct.setAccount_ID(line.getAmtAcctCr().doubleValue() == 0 ? accountID2 : accountID1);
			acct.setC_AcctSchema_ID(1000000);
			acct.setC_Period_ID(c_period_id);
			acct.setAD_Table_ID(224);
			acct.setRecord_ID(journal.get_ID());
			acct.setGL_Category_ID(batch.getGL_Category_ID());
			acct.setC_Currency_ID(batch.getC_Currency_ID());
			acct.setDateAcct(journal.getDateAcct());
			acct.setDateTrx(journal.getDateAcct());
			acct.setPostingType("A");
			acct.save();
		}
		
		boolean isSuccess = false;
		documentNo = "";
		journals[0].setDocStatus(MJournalBatch.STATUS_Voided);
		journal.setDocStatus(MJournalBatch.STATUS_Reversed);
		batch.setDocStatus(MJournalBatch.STATUS_Voided);
		batch2.setDocStatus(MJournalBatch.STATUS_Reversed);
		
		journals[0].setDocAction(MJournalBatch.ACTION_Reject);
		journal.setDocAction(MJournalBatch.ACTION_Reject);
		batch.setDocAction(MJournalBatch.ACTION_Reject);
		batch2.setDocAction(MJournalBatch.ACTION_Reject);

		if (!journals[0].save()) {
			Log.log(Level.SEVERE, "Journal not saved - "+batch.getDocumentNo()+ " " +journals[0].getDocumentNo());
		} 
		if (!journal.save()) {
			Log.log(Level.SEVERE, "Journal not saved - "+batch.getDocumentNo()+ " " +journal.getDocumentNo());
		} 
		
		if (!batch2.save()) {
			Log.log(Level.SEVERE, "Journal not saved - "+batch2.getDocumentNo());
		} 
		if (!batch.save()) {
			Log.log(Level.SEVERE, "Journal not saved - "+batch.getDocumentNo());
		} 
		return isSuccess;
	}
}
